/* 
 * File:   ParametersCommand.h
 * Author: Gab'z
 *
 * Created on 5 juin 2012, 10:58
 */

#ifndef PARAMETERSCOMMAND_H
#define	PARAMETERSCOMMAND_H

#include "../UndoableRedoableCommand.h"

namespace calculator {
    class Parameters;

    class ParametersCommand : public UndoableRedoableCommand {
    public:

        /**
         * Vérifie si la commande est exécutable.
         * Une commande modifiant les paramètres est toujours exécutable
         * Si un paramètre d'entrée est incorrect, il sera réglé sur les limites
         * acceptables @see Parameters
         * @return std::string("") (toujours exécutable) @see Command
         */
        virtual std::string isExecutable() const;

        /**
         * Méthode d'entrée du Design Pattern Command.
         * Utilisation avec le Design Pattern Template Method, appelle la méthode
         * apply(Parameters* parameters), une ParametersCommand ayant pour but 
         * de modifier un ou plusieurs paramètres
         */
        virtual void execute() const throw (CommandException);

        /**
         * Clone l'opérateur.
         * On ne peut pas créer de commandes (sauf des constantes) directement,
         * c'est le rôle du CommandManager, on a cependant besoin de les copier
         * pour les sauvegardes et la fonction UNDO/REDO.
         * @return une copie de la commande
         */
        virtual ParametersCommand* clone() const = 0;

    protected:

        /**
         * Crée un Memento propre à chaque Command contenant une copie
         * des données qui vont être modifiées.
         * @return un Memento spécialisé.
         */
        virtual const Memento* createMemento() const throw (CommandException) = 0;

        /**
         * Restaure les paramètre dans leur état précédent
         * @param memento le Memento contenant les paramètres à restituer.
         */
        virtual void restoreFromMemento(const Memento* memento) const throw (MementoException) = 0;

        /**
         * Méthode appelée par execute() via un Template Method.
         * @param parameters les paramètres à appliquer au Context de l'application
         */
        virtual void apply(Parameters* parameters) const = 0;

        /**
         * Constructeur de ParametersCommand.
         * Chaque ParametersCommand est défini par son nom. @see UndoableRedoableCommand
         * @param name le nom de la commande.
         */
        ParametersCommand(const std::string name);
        
        /**
         * Destructeur de ParametersCommand.
         */
        virtual ~ParametersCommand();

    private:
        static Logger* log;
    };
}

#endif	/* PARAMETERSCOMMAND_H */

